


import java.util.List;








/**
 * The Master is managing all Workers.
 * The number of Worker depends on the number of Processors and the number of Planets.
 * @author mac_fly
 * 
 * @return
 * @param 	PlanetList,
 * 			ZentralGestirn,
 * 			delta_t,
 * 			numberOfRuns
 */
public class Master {
	
	private List<Body> 			bodyList;				// List of all Planets except the ZentralGestirn
	private Body 				zentralGestirn;				// The Planet ZentralGestirn
	private int 					delta_t;					// Time between each Calculation
	private DummyObject o = 		new DummyObject();			// new DummyObject given by param
	private int counterJob = 		0;							// Counter for work
	private int numberOfAnswers = 	0;							// Counter for done work
	private int numberOfThreads;								// number of started Threads
	private int numberOfRuns;								// number of the entire Runs
	private int numberOfDoneRuns = 0;
	
	public Master(List<Body> bodyList, Body centralBody, int delta_t, int numberOfRuns)
	{
		this.bodyList = bodyList;
		this.zentralGestirn = centralBody;
		this.delta_t = delta_t;
		this.numberOfRuns = numberOfRuns;
	}

	public void startWorker()									// Starts the workers
	{	
		Runtime runtime = Runtime.getRuntime();
		int nrOfProcessors = runtime.availableProcessors();		// Asking how much Processors do we have
		if(nrOfProcessors > bodyList.size())				// If we have 30 Processors but only 
		{														// 5 Planets to calculate, we only need		
			numberOfThreads = bodyList.size();				// 5 Worker
		}
		else
		{
			numberOfThreads = nrOfProcessors;
		}
		
		for (int i = 0; i < numberOfThreads; i++)				// Start as many Worker as you have to
		{
			Thread workingThread = new Thread (new Worker(bodyList, zentralGestirn, delta_t, o, this));
			workingThread.start();
		}
		masterWait();											// Jump to MasterWait()and ask if you have to sleep
//		for(int numberOfDoneRuns = 1; numberOfDoneRuns <= numberOfRuns; numberOfDoneRuns++)
		while(true)
		{	
			if(getAmountAnswers() == bodyList.size())
			{
				counterJob = 0;										// Resetting CounterJob
				numberOfAnswers = 0;								// Resetting number of Answers
				
				for (Body currentBody : bodyList) 					// For each Planet do NewPosition to OldPosition
				{													// and NewPosition to Null
					currentBody.setPosition(currentBody.getNewPosition());
				
//					System.out.println(currentBody.getNewPosition() == null);
	//				currentBody.setNewPosition(new Vector3d());
//					currentBody.setNewPosition(null);
				}
				numberOfDoneRuns++;
				if (numberOfDoneRuns == numberOfRuns)
				{
					break;
				}
				o.release();										// Release all Workers
			}
			else masterWait(); 										// Jump to MasterWait()and ask if you have to sleep
		}
	}
	
	public synchronized int getCounterJob()
	{
		counterJob++;
		if(counterJob > bodyList.size())
			return bodyList.size()+1;
		return counterJob;
	}
	
	public synchronized int getAmountAnswers()
	{
		return numberOfAnswers;
	}
	
	public int getNumberOfThreads()
	{
		return numberOfThreads;
	}
	
	public synchronized void setAmountAnswers()
	{
		numberOfAnswers = numberOfAnswers +1;
	}
		
	public synchronized void masterWakeUp()							// Wakes up the Master
	{
		this.notify();
	}
		
	public synchronized void masterWait()							// Ask if you really have to sleep
	{
//
		  
			  try 
			   {
				    if (getAmountAnswers() < bodyList.size()) 	// If work is done, you dont have to sleep
				    { 
				    	this.wait();
				    }
			   } 
			   catch (InterruptedException e) 
			   {
				   e.printStackTrace();
			   }
		
	}
	
	
	
	
}
